import {Injectable} from '@angular/core';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';
import {CacheService} from '@kylin/cache';
import {ConfigService} from '@kylin/config';
import {Observable} from 'rxjs';
import * as _ from 'lodash';

@Injectable()
export class RequestInterceptor implements HttpInterceptor {

    hostname: string;
    private config = this.configService.httpInterceptorsConfig();

    constructor(private configService: ConfigService,
                private cacheService: CacheService) {
        this.hostname = this.configService.hostname;
    }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(this.defaultHeaders(req));
    }

    /**
     * 登陆接口不需要带Authorization,所以需要单独处理一下
     * @param req
     */
    private defaultHeaders(req: HttpRequest<any>) {   // 如果要使用网关功能,这里url就是this.gatewayHandleReqUrl,不使用就返回this.handleReqUrl
        if (req.url === '/login' || req.url === '/add/user') {
            return req.clone({
                url: this.handleReqUrl(req.url)
            });
        } else {
            const access_token = this.cacheService.get('token');
            return req.clone({
                url: this.handleReqUrl(req.url),
                setHeaders: {
                    'Authorization': `${access_token}`
                }
            });
        }
    }

    private handleReqUrl(url: string): string {
        if (url.startsWith('http://')) {
            return url;
        } else {
            return this.hostname + url;
        }
    }

    // 下面是结合网关的的功能
    private gatewayHandleReqUrl(url: string): string {
        if (url.startsWith('http://')) {
            if (url.startsWith('http://192.') && this.config.gatewayServer.enable) {
                if (this.config.gatewayServer.forward) {
                    return this.hostname + this.fetchRealUrl(this.removeUrlHostname(url));
                } else {
                    return this.hostname.substring(0, this.hostname.lastIndexOf(':')) + this.removeUrlHostname(url);
                }
            } else {
                return url;
            }
        } else {
            if (this.config.gatewayServer.enable) {
                if (this.config.gatewayServer.forward) {
                    return this.hostname + this.fetchRealUrl(url);
                } else {
                    return this.hostname.substring(0, this.hostname.lastIndexOf(':')) + ':' + this.fetchRealUrl(url);
                }
            } else {
                return this.hostname + url;
            }
        }
    }

    private removeUrlHostname(url: string): string {
        if (this.config.gatewayServer.forward) {
            const target = url.split(':')[2];
            return target.substring(target.indexOf('/'));
        } else {
            const target = url.split(':')[2];
            return ':' + target;
        }
    }

    fetchRealUrl(url: string): string {
        let pathData = {};
        if (this.config.gatewayServer.forward) {
            pathData = {
                map: '/api-m',  // 8091
                user: '/api-u', // 8000
                file: '/api-f',  // 8090
                // map: '8091',
                // user: '8000',
                // file: '8090',
            }
        } else {
            pathData = {
                // map: '/api-m',  // 8091
                // user: '/api-u', // 8000
                // file: '/api-f',  // 8090
                map: '8091',
                user: '8000',
                file: '8090',
            }
        }

        const controlData = {
            '/layer': 'map',
            '/layerLabel': 'map',
            '/layersLayer': 'map',
            '/organization': 'user',
            '/swaggerList': 'user',
            '/users': 'user',
            '/users-anon': 'user',
            '/roles': 'user',
            '/oauth': 'user',
            '/remove_token': 'user',
            '/files': 'file',
            '/smsVerify': 'user'
        };
        let result = url;
        _.forIn(controlData, (value, key) => {
            if (url.indexOf(key) !== -1) {
                result = pathData[value] + url;
            }
        });
        return result;
    }
}

